package com.xc.stock.infrastructure.db.config;

import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.rp.spring.jpa.GenericJpaRepositoryFactoryBean;
import com.rp.spring.jpa.GenericJpaRepositoryImpl;

/**
 * 
 * title: PlatformDatasourceConfig.java 
 * 平台数据源设置
 *
 * @author rplees
 * @email rplees.i.ly@gmail.com
 * @version 1.0  
 * @created Jan 26, 2018 3:57:47 PM
 */
@Configuration
@ComponentScan({ "com.xc.stock.infrastructure.db.po", "com.xc.stock.infrastructure.db.repo" })
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", 
transactionManagerRef = "transactionManager", 
repositoryBaseClass = GenericJpaRepositoryImpl.class, 
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class, 
basePackages = {
	"com.xc.stock.infrastructure.db.po", "com.xc.stock.infrastructure.db.repo",
	})
@PropertySources({
	@PropertySource("classpath:jpa.properties"),
})
@EnableConfigurationProperties(JpaProperties.class)
public class MarketDatasourceConfig {
	@Primary
	@Bean(name = "stockJpaProperties")
	@ConfigurationProperties(prefix = "spring.jpa")
	public JpaProperties jpaProperties() {
		return new JpaProperties();
	}
	
	@Primary
	@Bean
	@ConfigurationProperties(prefix = "spring.jpa.hibernate")
	public HibernateProperties hibernateProperties() {
		return new HibernateProperties();
	}
	
	@Bean
	@ConditionalOnMissingBean
	public JpaVendorAdapter jpaVendorAdapter(JpaProperties properties) {
		AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
		adapter.setShowSql(properties.isShowSql());
		if (properties.getDatabase() != null) {
			adapter.setDatabase(properties.getDatabase());
		}
		if (properties.getDatabasePlatform() != null) {
			adapter.setDatabasePlatform(properties.getDatabasePlatform());
		}
		adapter.setGenerateDdl(properties.isGenerateDdl());
		return adapter;
	}

	@Primary
	@Bean(name = {"stockEntityManagerFactory", "entityManagerFactory"})
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            @Qualifier("stockJpaProperties") JpaProperties jpaProperties,
            DataSource dataSource, Environment env, HibernateProperties hibernateProperties, JpaVendorAdapter jpaVendorAdapter, ObjectProvider<PersistenceUnitManager> persistenceUnitManager) {
		Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
		EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter,
				jpaProperties.getProperties(), persistenceUnitManager.getIfAvailable());
        return builder
                .dataSource(dataSource)
                .properties(properties)
                .packages( "cn.stock.**.po","cn.qutaojing.**.po", "com.xc.stock.infrastructure.db.**.po")
                .persistenceUnit("stock")
                .build();
    }
	
	@Primary
	@Bean(name = {"stockTransactionManager", "transactionManager"})
    public PlatformTransactionManager transactionManager(@Qualifier("stockEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}
